<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 字面量对象(普通对象) => 特点: 可以对应属性名,对对象中的数据进行增删改查!!
     var zhang = { // new Object()
        name:"张三",
        age:18,
        height:"177cm",
        weight:"70kg",
    }


    // zhang.sex = "男"; // 对象赋值时,赋一个不存在的属性,就会新增
    // delete zhang.height;
    // delete zhang.weight;
    // zhang.name = "李四";

    // console.log(zhang);


    // 除字面量对象和构造函数以外, 还有其他方式可以定义对象的属性

    /* 
       构造函数Object的方法  
       Object.defineProperty(targetObj,key,desc)   给对象新增属性,同时配置该属性的相关信息 (此方式也可以修改现有的desc配置,前提 configurable:true)
            targetObj  新增属性的对象
            key        新增的键名(属性名) 
            desc       对新增属性的描述(对象类型)
                value:         新增属性的属性值
                writable       属性是否可以被修改 (对应键名修改健值) => 默认false
                enumerable     属性是否可以枚举(循环遍历)  => 默认false
                configurable   属性是否可以被重新配置或删除  => 默认false  

                get:function(){}  取值拦截
                set:function(val){}  取值拦截

                注意: 使用拦截器时, 不能和value属性,writable属性同时使用

       Object.defineProperties(targetObj,params)
            targetObj  新增属性的对象
            params     对象参数,包含新增的属性和属性的秒数{key:desc}
  
   */

    var zhang = {};
    var _defaultName = "张三";
    Object.defineProperty(zhang, "name", {
        // value: "张三",  // 新增属性的属性值
        // writable: false, // 属性是否可以被修改 (对应键名修改健值) => 默认false
        enumerable: false, // 属性是否可以枚举(循环遍历)  => 默认false
        configurable: true,  // 属性是否可以被重新配置或删除  => 默认false  

        get:function(){ // 取值回调(拦截器)  => 回调函数的返回值就是对应属性取值的结果(zhang.name)
            console.log("取值拦截");
            // return zhang.name;  //一直触发取值拦截 => 死递归
            return _defaultName; // 如果此处注释,函数默认返回undefined => 可以理解为此属性不允许取值
        },
        set:function(val){ // 赋值回调(拦截器   zhang.name = "李四"  val(形参) => 用于接收被赋予的值
            console.log("赋值拦截",val);
            // zhang.name = val; // 一直触发赋值拦截   => 死递归
            // _defaultName = val;  // 如果此处注释, 没有变量记录存储的数据 => 可以理解为此属性不允许被修改
        }
    })

    Object.defineProperty(zhang, "age", {
        value: 18,  // 新增属性的属性值
        writable: true, // 属性是否可以被修改 (对应键名修改健值) => 默认false
    })

    Object.defineProperty(zhang, "height", {
        value: "177cm",  // 新增属性的属性值
        writable: true, // 属性是否可以被修改 (对应键名修改健值) => 默认false
    })

    Object.defineProperty(zhang, "weight", {
        value: "65kg",  // 新增属性的属性值
        writable: true, // 属性是否可以被修改 (对应键名修改健值) => 默认false
    })

   
    console.log(zhang);

    console.log(zhang.name); // 取值

    zhang.name = "王五"; // 赋值 

    console.log(zhang);



</script>

</html>